package com.ld.security.common.mybatis.base.service;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ld.security.common.core.base.ESuperEntity;
import com.ld.security.common.core.base.SuperPo;
import com.ld.security.common.core.util.*;
import com.ld.security.common.mybatis.base.mapping.SuperMapping;
import com.ld.security.common.mybatis.base.po.IdsPo;
import com.ld.security.common.mybatis.base.po.ListPo;
import com.ld.security.common.mybatis.base.po.PagePo;
import com.ld.security.common.mybatis.base.vo.PageVo;
import com.ld.security.common.mybatis.core.wrapper.EntityWrapper;
import com.ld.security.common.mybatis.core.wrapper.WrapperFactory;
import com.ld.security.common.mybatis.event.DeleteEvent;
import com.ld.security.common.mybatis.event.SaveEvent;
import com.ld.security.common.mybatis.util.JdbcUtil;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


public abstract class ISuperServiceImpl<E extends ESuperEntity> implements ISuperService<E> {

    @Autowired
    protected SuperMapping<E> superMapping;

    /**
     * 拦截链,对象预处理使用
     */
    @Autowired
    WrapperFactory wrapperFactory;

    @Autowired(required = false)
    List<SaveEvent> saveEvents = Arrays.asList();

    protected boolean hasEntity(String id){
        if(ReflectionUtil.isNull(id)){
            return false;
        }
        return superMapping.selectById(id) != null;
    }






    @Override
    public  List<E> all(SuperPo po) {
        EntityWrapper ew =  this.getWrapper(po);
        List<E> list =  this.superMapping.selectList(ew);

        return list;
    }


    @Override
    public E findOne(SuperPo po) {
        List<E> list =  this.all(po);
        return list.isEmpty()?null:list.get(0);
    }

    @Override
    public List<E> all() {
        return superMapping.selectList(new QueryWrapper<>());
    }

    @Override
    public List<E> listByIds(Collection<String> ids) {
        return superMapping.selectBatchIds(ids);
    }

    protected void saveBefore(E e,boolean insert){
        for (SaveEvent saveEvent : saveEvents) {
            saveEvent.saveBefore(e);
        }
    }


    protected void saveAfter(E e,boolean insert){
        for (SaveEvent saveEvent : saveEvents) {
            saveEvent.saveAfter(e);
        }
    }

    @Override
    public int save(E entity) {

        int total = 0;

        if(StringUtil.isNull(entity.getId())){
            entity.setId(UuidUtil.getId());
            entity.setCrtTime(new Date());
            entity.setUptTime(new Date());
            ReflectionUtil.fill(entity);
            this.saveBefore(entity,true);
            total = superMapping.insert(entity);
            this.saveAfter(entity,true);
        }else{
            synchronized (this){
                if(this.hasEntity(entity.getId())){

                    this.saveBefore(entity,false);
                    entity.setUptTime(new Date());
                    total = superMapping.updateById(entity);
                    this.saveAfter(entity,false);
                }else{
                    entity.setCrtTime(new Date());
                    entity.setUptTime(new Date());
                    ReflectionUtil.fill(entity);
                    this.saveBefore(entity,true);
                    total =  superMapping.insert(entity);
                    this.saveAfter(entity,true);

                }
            }
        }


        return total;
    }


    @Override
    public int saveBatch(Collection<E> entityList) {
        int total = 0;
        for (E e : entityList) {
            total += this.save(e);
        }
        return total;
    }

    @Override
    public E getById(String id) {
        return superMapping.selectById(id);

    }



    @Override
    public boolean removeById(String id) {
        int total = this.removeByIds(Arrays.asList(id));
        return total > 0;
    }



    @Override
    public int removeByIds(Collection<String> ids) {


    int total =     superMapping.deleteBatchIds(ids);



        return total;

    }

    @Override
    public PageVo<E> page(PagePo po) {

        //查询对象预处理

        Page<E> page = po.toPage();
        EntityWrapper ew =  this.getWrapper(po);
        superMapping.page(ew,page);

        PageVo vo = PageVo.of(page);


        return vo;
    }

    @Override
    public int count(SuperPo query) {
        EntityWrapper ew =  this.getWrapper(query);
        return this.superMapping.count(ew);
    }




    protected void proxyQuery(Collection vals){
        for (Object val : vals) {
            JdbcUtil.proxyQuery(val);
        }

    }
    protected void proxyQuery(Object val){
        JdbcUtil.proxyQuery(val);
    }

    protected void proxySave(Object val){
        JdbcUtil.proxySave(val);
    }
    protected void proxyRemove(Object val){
        JdbcUtil.proxyRemove(val);
    }

    protected EntityWrapper getWrapper(SuperPo po){

        return wrapperFactory.getWrapper(po);
    }

    @Override
    public List<E> all(EntityWrapper ew) {
        return superMapping.all(ew);
    }

    protected  EntityWrapper getWrapper(){
        return wrapperFactory.getWrapper();
    }
}
